package com.imis.module.system.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imis.base.annotation.HashCache;
import com.imis.base.annotation.HashCacheEvict;
import com.imis.base.constant.CacheConstant;
import com.imis.base.constant.CommonConstant;
import com.imis.base.constant.DataBaseConstant;
import com.imis.module.base.impl.BaseServiceImpl;
import com.imis.module.system.dao.SysRoleMapper;
import com.imis.module.system.model.converter.SysMenuConverter;
import com.imis.module.system.model.converter.SysRoleConverter;
import com.imis.module.system.model.po.SysRole;
import com.imis.module.system.model.po.SysRoleMenu;
import com.imis.module.system.model.ro.PagingQueryRoleDTO;
import com.imis.module.system.model.ro.PagingQueryUserRoleDTO;
import com.imis.module.system.model.ro.SysGrantMenuPermissionToRoleRO;
import com.imis.module.system.model.ro.SysRoleUpdateRO;
import com.imis.module.system.model.vo.SysRoleVO;
import com.imis.module.system.service.ISysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 系统角色表-菜单权限组 服务实现类
 * </p>
 *
 * @author XinLau
 * @since 2020-03-12
 */
@Service
@Slf4j
@DS(DataBaseConstant.DATA_SOURCE_MASTER)
public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    /**
     * 分页查询角色信息
     *
     * @param pagingQueryRoleDTO - 角色查询对象
     * @return Page<SysRoleVO> - 角色信息
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/16 09:30
     */
    @Override
    public Page<SysRoleVO> pagingQuerySysRoleListByParameter(final PagingQueryRoleDTO pagingQueryRoleDTO) {
//        1.页码、页长
        Page<SysRole> sysRolePage = new Page<>(pagingQueryRoleDTO.getPageNumber(), pagingQueryRoleDTO.getPageSize());
//        2.排序字段
        sysRolePage.addOrder(OrderItem.descs(DataBaseConstant.CREATE_TIME_TABLE, DataBaseConstant.UPDATE_TIME_TABLE));
//        3.条件分页查询
        sysRolePage = mapper.pagingQuerySysRoleListByParameter(sysRolePage, pagingQueryRoleDTO);
//        4.PO分页对象转VO实体分页对象
        return SysRoleConverter.INSTANCE.pagePo2pageVo(sysRolePage);
    }

    /**
     * 根据角色名查询角色信息
     *
     * @param roleName - 角色名
     * @return SysRole - 角色
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/12 17:30
     */
    @Override
    public SysRole queryRoleByName(final String roleName) {
        return mapper.selectOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleName, roleName));
    }

    /**
     * 根据角色编码查询角色信息
     *
     * @param roleCode - 角色编码
     * @return SysRole - 角色
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/12 17:30
     */
    @Override
    public SysRole queryRoleByCode(final String roleCode) {
        return mapper.selectOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, roleCode));
    }

    /**
     * 创建角色信息
     *
     * @param sysRole - 角色
     * @return Boolean
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/12 17:30
     */
    @Override
    public Boolean saveRole(final SysRole sysRole) {
//        影响行数
        int insert = mapper.insert(sysRole);
        return insert > 0;
    }

    /**
     * 删除角色信息
     *
     * @param roleIdentification - 角色标识
     * @return Boolean
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/12 17:30
     */
    @Override
    public Boolean deleteRole(final Long roleIdentification) {
//        影响行数
        int delete = mapper.deleteById(roleIdentification);
        return delete > 0;
    }

    /**
     * 清除角色权限信息
     *
     * @param roleIdentification - 角色标识
     * @return Boolean
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/12 17:30
     */
    @Override
    @HashCacheEvict(hashIdentification = CacheConstant.PREFIX_SYS_ROLE_PERMISSIONS, hashKey = "'ROLE_ID_' + #roleIdentification")
    public Boolean cleanRolePermissionsById(final Long roleIdentification) {
        try {
//            影响行数
            int delete = mapper.cleanRolePermissionsById(roleIdentification);
            return Boolean.TRUE;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Boolean.FALSE;
        }
    }

    /**
     * 根据角色编号查询用户编号
     *
     * @param roleIdentification - 角色标识
     * @return Long[]
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/16 09:30
     */
    @Override
    public List<Long> selectSysUserIdArrayByRoleId(final Long roleIdentification) {
        return mapper.selectSysUserIdArrayByRoleId(roleIdentification);
    }

    /**
     * 根据用户编号查询角色编号
     *
     * @param userIdentification - 户户标识
     * @return Long[]
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/16 09:30
     */
    @Override
    @HashCache(hashIdentification = CacheConstant.PREFIX_SYS_USER_ROLE, hashKey = "'USER_ID_' + #userIdentification")
    public List<Long> selectSysRoleIdArrayByUserId(final Long userIdentification) {
        return mapper.selectSysRoleIdArrayByUserId(userIdentification);
    }

    /**
     * 根据角色编号修改角色信息
     *
     * @param sysRoleUpdate - 角色修改对象
     * @return Boolean
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/16 09:30
     */
    @Override
    public Boolean updateByRoleIdentification(final SysRoleUpdateRO sysRoleUpdate) {
//        影响行数
        int update = mapper.updateById(SysRoleConverter.INSTANCE.updateRo2domain(sysRoleUpdate));
        return update > 0;
    }

    /**
     * 分页查找已授权角色
     *
     * @param sysUserRoleSelect - 授权角色查询对象
     * @return Page<SysRoleVO> -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/20 15:33
     */
    @Override
    public Page<SysRoleVO> pagingQueryGrantRoleListByParameter(final PagingQueryUserRoleDTO sysUserRoleSelect) {
//        1.页码、页长
        Page<SysRole> sysRolePage = new Page<>(sysUserRoleSelect.getPageNumber(), sysUserRoleSelect.getPageSize());
//        2.排序字段
        sysRolePage.addOrder(OrderItem.descs(DataBaseConstant.CREATE_TIME_TABLE, DataBaseConstant.UPDATE_TIME_TABLE));
//        3.条件分页查询
        sysRolePage = mapper.pagingQueryRoleListByParameter(sysRolePage, sysUserRoleSelect);
//        4.PO分页对象转VO实体分页对象
        return SysRoleConverter.INSTANCE.pagePo2pageVo(sysRolePage);
    }

    /**
     * 分页查找未授权角色
     *
     * @param sysUserRoleSelect - 授权角色查询对象
     * @return Page<SysRoleVO> -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/20 15:33
     */
    @Override
    public Page<SysRoleVO> pagingQueryNotGrantRoleListByParameter(final PagingQueryUserRoleDTO sysUserRoleSelect) {
//        1.页码、页长
        Page<SysRole> sysRolePage = new Page<>(sysUserRoleSelect.getPageNumber(), sysUserRoleSelect.getPageSize());
//        2.排序字段
        sysRolePage.addOrder(OrderItem.descs(DataBaseConstant.CREATE_TIME_TABLE, DataBaseConstant.UPDATE_TIME_TABLE));
//        3.条件分页查询未授权角色
        sysUserRoleSelect.setContain(CommonConstant.ROLE_NOT_GRANT);
        sysRolePage = mapper.pagingQueryRoleListByParameter(sysRolePage, sysUserRoleSelect);
//        4.PO分页对象转VO实体分页对象
        return SysRoleConverter.INSTANCE.pagePo2pageVo(sysRolePage);
    }

    /**
     * 为角色授权功能菜单权限
     *
     * @param sysGrantMenuPermissionToRole - 角色授权功能菜单
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/21 10:59
     */
    @Override
    public Boolean grantMenuPermissionsToRole(final SysGrantMenuPermissionToRoleRO sysGrantMenuPermissionToRole) {
        try {
//            1.清除之前的授权
            Long roleId = sysGrantMenuPermissionToRole.getRoleId();
//            影响的的行数
            Boolean aBoolean = cleanRolePermissionsById(roleId);
//            对象转换
            List<SysRoleMenu> sysRoleMenuList = SysMenuConverter.INSTANCE.sysGrantMenuPermissionToRoleRo2SysUserRoles(sysGrantMenuPermissionToRole);
//            2.授权处理
            int grant = mapper.grantMenuPermissionsToRole(sysRoleMenuList);
            return Boolean.TRUE;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Boolean.FALSE;
        }
    }

}